package com.system.vote.admin.aspect;

import cn.hutool.core.util.ArrayUtil;
import com.system.vote.admin.annotation.GlobalInterceptor;
import com.system.vote.common.utils.StringUtils;
import com.system.vote.core.annotation.VerifyParam;
import com.system.vote.admin.exception.BusinessException;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.Arrays;

@Aspect
@Component
public class OperationAspect {
    private final Logger logger = LoggerFactory.getLogger(OperationAspect.class);

    private static final String[] BASE_TYPE_PARAM = new String[]{"java.lang.String", "java.lang.Integer", "java.lang.Long", "java.util.Date"};

    @Before("@annotation(com.system.vote.admin.annotation.GlobalInterceptor)")
    private void interceptorDo(JoinPoint joinPoint) throws BusinessException {
        //切点表达式定义方法，方法修饰符可以private或public
        logger.info(Arrays.toString(joinPoint.getArgs()));
        Object[] argument = joinPoint.getArgs();
        Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
        logger.info("方法名:{}", method.getName());
        GlobalInterceptor globalInterceptor = method.getAnnotation(GlobalInterceptor.class);
        if (globalInterceptor == null) {
            return;
        }
        /**
         * 校验参数
         */
        if (globalInterceptor.checkParam()) {
            validateParams(method, argument);
        }

    }

    private void validateParams(Method method, Object[] argument) throws BusinessException {
        Parameter[] parameters = method.getParameters();
        for (int i = 0; i < parameters.length; i++) {
            Parameter parameter = parameters[i];
            Object value = argument[i];
            VerifyParam verifyParam = parameter.getAnnotation(VerifyParam.class);
            if (verifyParam == null) {
                continue;
            }
            String paramTypeName = parameter.getParameterizedType().getTypeName();
            if (ArrayUtil.contains(BASE_TYPE_PARAM, paramTypeName)) {
                checkValue(value, verifyParam);
            } else {
                logger.info("obj");
            }
        }
    }

    private void checkValue(Object value, VerifyParam verifyParam) throws BusinessException {
        boolean isEmpty = value == null || StringUtils.isEmpty(value.toString());
        int length = value == null ? 0 : value.toString().length();
        if (isEmpty && verifyParam.required()) {
            throw new BusinessException("参数错误");
        }
        if (!isEmpty && (verifyParam.max() != -1 && verifyParam.max() > length || verifyParam.min() != -1 && verifyParam.min() < length)) {
            throw new BusinessException("参数错误");
        }
    }
}
